/**
 * cocos功能的扩展
 */
export const node = {
    /**
     * 得到一个node相对于target坐标系下的坐标
     */
    convertNodeToNodeSpaceAR(target: cc.Node, node: cc.Node, pos?: cc.Vec2 | cc.Vec3) {
        if (node.is3DNode) {
            return target.convertToNodeSpaceAR(node.convertToWorldSpaceAR(pos || cc.Vec3.ZERO));
        } else {
            return target.convertToNodeSpaceAR(node.convertToWorldSpaceAR(pos || cc.Vec2.ZERO));
        }
    },

    /**
     * 得到一个node相对于target坐标系下的坐标
     */
    convertNodeToNodeSpace(target: cc.Node, node: cc.Node, pos?: cc.Vec2 | cc.Vec3) {
        if (node.is3DNode) {
            return target.convertToNodeSpaceAR(node.convertToWorldSpaceAR(pos || cc.Vec3.ZERO));
        } else {
            return target.convertToNodeSpaceAR(node.convertToWorldSpaceAR(pos || cc.Vec2.ZERO));
        }
    },

    /**
     * 得到一个node相对于target父坐标系下的坐标
     */
    convertNodeToParentSpaceAR(target: cc.Node, node: cc.Node, pos?: cc.Vec2 | cc.Vec3) {
        if (node.is3DNode) {
            return target.parent.convertToNodeSpaceAR(node.convertToWorldSpaceAR(pos || cc.Vec3.ZERO));
        } else {
            return target.parent.convertToNodeSpaceAR(node.convertToWorldSpaceAR(pos || cc.Vec2.ZERO));
        }
    },

    /**
     * 得到一个node相对于target父坐标系下的坐标
     */
    convertNodeToParentSpace(target: cc.Node, node: cc.Node, pos?: cc.Vec2) {
        // todo
        return target.parent.convertToNodeSpace(node.convertToWorldSpaceAR(pos || cc.Vec2.ZERO));
    },

    /**
     * 递归查找target所有父节点中第一个匹配指定类型的组件。
     * @method getComponentInParent
     * @param {Function|String} typeOrClassName
     * @return {cc.Component}
     */
    getComponentInParent(target: cc.Node, typeOrClassName: string | typeof cc.Component) {
        const scene = cc.director.getScene();
        let node = target;
        let com = null;
        while (node.parent && node.parent !== scene) {
            if (typeof typeOrClassName === 'string') {
                com = node.parent.getComponent(typeOrClassName);
            } else {
                com = node.parent.getComponent(typeOrClassName);
            }
            if (!com) {
                node = node.parent;
            } else {
                break;
            }
        }
        return com;
    },

    /**
     * 递归查找target所有父节点中指定类型的组件
     * @method getComponentsInParent
     * @param {Function|String} typeOrClassName
     * @return {cc.Component[]}
     */
    getComponentsInParent(target: cc.Node, typeOrClassName: string | typeof cc.Component) {
        const scene = cc.director.getScene();
        const coms = [];
        let node = target;
        let com = null;

        while (node && node !== scene) {
            if (typeof typeOrClassName === 'string') {
                com = node.getComponent(typeOrClassName);
            } else {
                com = node.getComponent(typeOrClassName);
            }
            if (!com) {
                node = node.parent;
            } else {
                coms.push(com);
            }
        }
        return coms;
    }
};